<template>
  <el-space direction="vertical">
    <!-- 上传按钮 -->
    <el-upload :show-file-list="false" :http-request="selectFile">
      <el-button type="primary">请选择文件</el-button>
    </el-upload>

    <!-- 这里不需要 进度条 -->
    <!-- <el-progress v-if="task" :percentage="task.percent" :status="task.uploading ? '' : 'success'">
      <span>{{ task.name }} — {{ task.uploading ? '上传中' : '已完成' }}, {{ task.percent.toFixed(2) + '%' }}</span>
    </el-progress> -->
  </el-space>
</template>

<script setup>
import { ref, computed } from 'vue'
import { ElMessage } from 'element-plus'

import { AUTHORIZATION, CODE_SUCCESS, wsUrl } from "@/common_js/common_variable"
import { getStatus } from '@/network/user/upload'
import { FILE_UPLOAD_SUCCESS, WebSOCKET_TYPE_MERGE, WebSOCKET_TYPE_ERROR, WebSOCKET_TYPE_CHUNK } from "@/common_js/userInteface_common"
import { catalogueAdd } from '@/network/user/api_catalogue'
import eventBus from '@/stores/eventBus' // 全局事件，属性目录使用

// 顶部引入仓库
import { taskList } from '@/stores/UploadTasks'

// 实时响应式目录 id
import { useDirStore } from '@/stores/dirStore'
const dirStore = useDirStore()
const currentDirId = computed(() => dirStore.currentDirId)

const CHUNK_SIZE = 2 * 1024 * 1024
// const CHUNK_SIZE = 60 * 1024
const task = ref(null)

// 计算文件 MD5（简易实现，生产环境请放 WebWorker）
import SparkMD5 from 'spark-md5'

async function calcMD5(file) {
  return new Promise((resolve, reject) => {
    const reader = new FileReader()
    reader.onload = e => resolve(SparkMD5.ArrayBuffer.hash(e.target.result))
    reader.onerror = reject
    reader.readAsArrayBuffer(file)
  })
}

async function selectFile({ file }) {
  const fileObj = file
  const taskId = crypto.randomUUID()
  const md5 = await calcMD5(fileObj)
  const totalChunks = Math.ceil(fileObj.size / CHUNK_SIZE)

  // 1. 先查询是否已有上传记录
  await getStatus(md5).then((res) => {
    console.log(res);
    const data = res.data;
    if (data.state == FILE_UPLOAD_SUCCESS) {
      const newFile = {
        "id": undefined,
        "catalogueId": undefined,
        "type": 1,
        "userId": undefined,
        "name": fileObj.name,
        "parentId": currentDirId.value
      }
      catalogueAdd(newFile).then(res => {
        if (res.code == CODE_SUCCESS) {
          ElMessage.success('文件上传成功');
          eventBus.emit('update-catalogue-list');
        }
      })
    } else {
      let token = localStorage.getItem(AUTHORIZATION)
      // 2. 建立 WebSocket
      const ws = new WebSocket(`${wsUrl}?Authorization=${encodeURIComponent(token)}`)
      let currentChunk = 0
      // task.value = { id: taskId, name: fileObj.name, percent: 0, uploading: true }
      taskList.unshift({ id: taskId, name: fileObj.name, percent: 0, uploading: true })

      // ws.onopen = () => ws.send('hello')
      console.log('正常运行');

      ws.onopen = () => sendChunk()
      ws.onmessage = e => {
        task.value = JSON.parse(e.data)
        const res = JSON.parse(e.data)          // 原始对象
        /* ---------- 新增：统一错误处理 ---------- */
        if (res.type === WebSOCKET_TYPE_ERROR) {
          // ws.close()
          ElMessage.error(res.msg)   // 使用 ElementPlus 消息提示
          return
        }
        /* ---------------------------------------- */
        console.log('原始数据', res)

        const idx = taskList.findIndex(t => t.id === taskId)
        if (idx === -1) return

        // 1. 计算百分比
        // const percent = Math.round((res.uploadedSize / res.totalSize) * 100) || 0
        // 2. 判断状态
        // const uploading = res.uploadedSize < res.totalSize
        console.log('进度：', res.percent);
        console.log('状态：', res.uploading);


        // 3. 真正赋值
        Object.assign(taskList[idx], {
          percent: res.percent,
          uploading: res.uploading,
          uploadedSize: res.uploadedSize,
          totalSize: res.totalSize
        })

        console.log('进度：', task.value.percent.toFixed(2) + '%')
        if (task.value.uploading) {
          currentChunk++
          sendChunk()
        } else {
          ws.close()
          ElMessage.success('上传完成')
          eventBus.emit('update-catalogue-list')
        }
      }

      function sendChunk() {
        if (currentChunk >= totalChunks) {
          /* 【修改点 2】合并指令仍用文本帧，体积小 */
          ws.send(JSON.stringify({ type: WebSOCKET_TYPE_MERGE, taskId, md5, parentId: currentDirId.value, fileName: fileObj.name }))
          return
        }

        const start = currentChunk * CHUNK_SIZE
        const end = Math.min(fileObj.size, start + CHUNK_SIZE)
        const blob = fileObj.slice(start, end)

        /* 【修改点 3】构造 128 字节 JSON 头 + 文件二进制 */
        const headerObj = {
          type: WebSOCKET_TYPE_CHUNK,
          taskId,
          md5,
          fileName: fileObj.name,
          totalSize: fileObj.size,
          chunkNumber: currentChunk + 1,
          chunkSize: blob.size,
          parentId: currentDirId.value
        }
        const headerStr = JSON.stringify(headerObj) + '\n'   // 用 \n 做分隔符
        const encoder = new TextEncoder()
        const headerBytes = encoder.encode(headerStr)

        const reader = new FileReader()
        reader.onload = e => {
          const chunkBytes = new Uint8Array(e.target.result)
          const merged = new Uint8Array(headerBytes.length + chunkBytes.length)
          merged.set(headerBytes, 0)
          merged.set(chunkBytes, headerBytes.length)

          ws.send(merged)   // 一条二进制帧
        }
        reader.readAsArrayBuffer(blob)
      }
    }
  }).catch(() => { })
}
</script>